package com;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Collection;
import java.util.Map;

/**
 * 断言。更多参见{@link org.springframework.util.Assert}
 */
public class AssertUtil {
    /**
     * 断言判断
     *
     * @param expression
     *            表达式
     * @param errMsg
     *            错误消息
     */
    public static void check(boolean expression, String errMsg) {
        if (!expression) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 最大长度
     *
     * @param input
     * @param maxSize
     *            最长度
     * @param errMsg
     */
    public static void maxSize(String input, int maxSize, String errMsg) {
        if (StringUtils.isBlank(input)) {
            return;
        }
        if (input.length() <= maxSize) {
            return;
        }
        throw new IllegalArgumentException(errMsg);
    }

    /**
     * 最大数量
     *
     * @param input
     * @param maxSize
     *            最大数
     * @param errMsg
     */
    public static void maxSize(Collection<?> input, int maxSize, String errMsg) {
        if (CollectionUtils.isEmpty(input)) {
            return;
        }
        if (input.size() <= maxSize) {
            return;
        }
        throw new IllegalArgumentException(errMsg);
    }

    /**
     * 最大数量
     *
     * @param input
     * @param maxSize
     *            最大数
     * @param errMsg
     */
    public static <T> void maxSize(T[] input, int maxSize, String errMsg) {
        if (ArrayUtils.isEmpty(input)) {
            return;
        }
        if (input.length <= maxSize) {
            return;
        }
        throw new IllegalArgumentException(errMsg);
    }

    /**
     * 最大数量
     *
     * @param input
     * @param maxSize
     *            最大数
     * @param errMsg
     */
    public static void maxSize(Map<?, ?> input, int maxSize, String errMsg) {
        if (MapUtils.isEmpty(input)) {
            return;
        }
        if (input.size() <= maxSize) {
            return;
        }
        throw new IllegalArgumentException(errMsg);
    }

    /**
     * 不为空或null
     *
     * @param paramName
     *            参数名
     */
    public static void hasText(String input, String paramName) {
        if (input == null || input.isEmpty()) {
            throw new IllegalArgumentException(paramName + " not all null or empty.");
        }
    }

    /**
     * 不为null
     *
     * @param obj
     * @param paramName
     *            参数名
     */
    public static void notNull(Object obj, String paramName) {
        if (obj == null) {
            throw new IllegalArgumentException(paramName + " not all null.");
        }
    }

    /**
     * 不为空或null
     *
     * @param s
     * @param errMsg
     *            错误信息
     */
    public static void notEmpty(String s, String errMsg) {
        if (StringUtils.isEmpty(s)) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 不为空或null
     *
     * @param errMsg
     *            错误信息
     */
    public static void notEmpty(Collection<?> list, String errMsg) {
        if (CollectionUtils.isEmpty(list)) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 不为空或null
     *
     * @param errMsg
     *            错误信息
     */
    public static <T> void notEmpty(T[] arr, String errMsg) {
        if (ArrayUtils.isEmpty(arr)) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 不为空或null
     *
     * @param errMsg
     *            错误信息
     */
    public static void notEmpty(Map<?, ?> map, String errMsg) {
        if (MapUtils.isEmpty(map)) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    public static void noNullElements(Object[] array, String errMsg) {
        if (array == null) {
            return;
        }
        for (Object element : array) {
            if (element == null) {
                throw new IllegalArgumentException(errMsg);
            }
        }
    }

    public static <T> void noNullElements(Collection<T> list, String errMsg) {
        if (list == null) {
            return;
        }
        for (T element : list) {
            if (element == null) {
                throw new IllegalArgumentException(errMsg);
            }
        }
    }

    public static void noNullElementValues(Map<?, ?> map, String errMsg) {
        if (map == null) {
            return;
        }
        for (Object element : map.values()) {
            if (element == null) {
                throw new IllegalArgumentException(errMsg);
            }
        }
    }

    /**
     * 值是否在数组
     */
    @SuppressWarnings("unchecked")
    public static <T> void in(T source, String errMsg, T... targets) {
        for (T item : targets) {
            if (source.equals(item)) {
                return;
            }
        }
        throw new IllegalArgumentException(errMsg);
    }

    /**
     * 值是否在数组
     */
    public static <T> void in(T source, T[] targets, String errMsg) {
        in(source, errMsg, targets);
    }

    /**
     * 值是否在数组
     */
    public static <T> void in(T source, Collection<T> targets, String errMsg) {
        for (T item : targets) {
            if (source.equals(item)) {
                return;
            }
        }
        throw new IllegalArgumentException(errMsg);
    }

    /**
     * 值是否在范围内
     *
     * @param input
     * @param min
     *            最小值(包含)
     * @param max
     *            最大值(包含)
     * @param errMsg
     */
    public static void range(long input, long min, long max, String errMsg) {
        if (input < min || input > max) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 值是否在范围内
     *
     * @param input
     * @param min
     *            最小值(包含)
     * @param max
     *            最大值(包含)
     * @param errMsg
     */
    public static void range(double input, double min, double max, String errMsg) {
        if (input < min || input > max) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 值是否在范围内
     *
     * @param input
     * @param min
     *            最小值(包含)
     * @param max
     *            最大值(包含)
     * @param errMsg
     */
    public static <T extends Comparable<T>> void range(T input, T min, T max, String errMsg) {
        if (input.compareTo(min) == -1 || input.compareTo(max) == 1) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 大于某值
     *
     * @param input
     * @param min
     *            最小值
     * @param errMsg
     */
    public static <T extends Comparable<T>> void greaterThan(T input, T min, String errMsg) {
        if (input.compareTo(min) < 1) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 大于或等于某值
     *
     * @param input
     * @param min
     *            最小值
     * @param errMsg
     */
    public static <T extends Comparable<T>> void greaterThanOrEqual(T input, T min, String errMsg) {
        if (input.compareTo(min) == -1) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 小于某值
     *
     * @param input
     * @param max
     *            最大值
     * @param errMsg
     */
    public static <T extends Comparable<T>> void lessThan(T input, T max, String errMsg) {
        if (input.compareTo(max) > -1) {
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * 小于或等于某值
     *
     * @param input
     * @param max
     *            最大值
     * @param errMsg
     */
    public static <T extends Comparable<T>> void lessThanOrEqual(T input, T max, String errMsg) {
        if (input.compareTo(max) == 1) {
            throw new IllegalArgumentException(errMsg);
        }
    }
}
